package com.yunhe.authority.repository.authority;

import com.yunhe.authority.domain.authority.RealStation;
import com.yunhe.authority.domain.authority.Station;
import com.yunhe.authority.domain.base.StationType;
import org.springframework.data.neo4j.annotation.Query;
import org.springframework.data.neo4j.repository.Neo4jRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * 电站Repository
 * @desc 电站仓库定义
 * @author liuronglei
 */
@Repository
public interface StationRepository extends Neo4jRepository<Station, Long> {
    /**
     * 根据电站编号获得电站对象
     * @param name 电站编号
     */
    Station findByName(String name);

    /**
     * 根据电站代码获得电站对象
     * @param code 电站代码
     */
    Station findByCode(Long code);

    /**
     * 电站绑定电站类型
     * @param id 电站ID
     * @param stationTypeId 电站类型ID
     */
    @Query("start n=node({id}),m=node({stationTypeId}) create (n)-[:STATIONTYPE_OF]->(m)")
    void bindStationTypeById(@Param("id") Long id, @Param("stationTypeId") Long stationTypeId);

    /**
     * 电站解绑电站类型
     * @param id 电站ID
     */
    @Query("start n=node({id}) match (n)-[r:STATIONTYPE_OF]->() delete r")
    void unbindStationTypeById(@Param("id") Long id);

    /**
     * 根据电站获得电站类型
     * @param id ID
     */
    @Query("start n=node({id}) match(n)-[:STATIONTYPE_OF]->(m) return m")
    StationType findStationTypeById(@Param("id") Long id);

    /**
     * 根据电站类型获得电站
     * @param stationTypeId 电站类型ID
     */
    @Query("start n=node({stationTypeId}) match (s:Station)-[:STATIONTYPE_OF]->(n) return s")
    Iterable<Station> findStationsByStationTypeId(@Param("stationTypeId") Long stationTypeId);

    @Query("match(f:Firm)-[r]->(s:Station{code:{code}}) delete r")
    void unbindFirmByCode(@Param("code") Long code);

//    @Query("match(f:Firm{code:{firmCode}})-[]->(s:Station)-[]->(a:Area) where f.title contains {queryStr} or " +
//            "s.title contains {queryStr} or a.title contains {queryStr} " +
//            "with s match(s)-[]->(t:StationType{code:{typeCode}}) " +
//            "return s order by {sort} skip {page}*{size} limit {size}")
//    Iterable<Station> search(@Param("firmCode") Optional<Long> firmCode,
//                             @Param("typeCode") Optional<Long> typeCode,
//                             @Param("queryStr") Optional<String> queryStr,
//                             @Param("page") int page,
//                             @Param("size") int size,
//                             @Param("sort") String sort);
//
//    @Query("match(f:Firm{code:{firmCode}})-[]->(s:Station)-[]->(a:Area) " +
//            "with s match(s)-[]->(t:StationType{code:{typeCode}}) " +
//            "return s order by {sort} DESC skip {page}*{size} limit {size}")
//    Iterable<Station> search(@Param("firmCode") Long firmCode,
//                             @Param("typeCode") Long typeCode,
//                             @Param("page") int page,
//                             @Param("size") int size,
//                             @Param("sort") String sort,
//                             @Param("order") String order);

    /**
     * 判断设备是否被绑定电站
     * @param devId 设备ID
     */
    @Query("start dev=node({devId}) match p=(s:Station)-[:HAS_RESOURCE]->(dev) return length(p)>0")
    Boolean isBindStation(@Param("devId") Long devId);

    /**
     * 根据设备代码查找所属电站
     * @param devCode 设备代码
     */
    @Query("match(s:Station)-[:HAS_RESOURCE]->(dev{code:{devCode}}) return s limit 1")
    Station findStationByDevCode(@Param("devCode") Long devCode);

    /**
     * 根据单位和电站名称查找电站
     * @param firmCode 单位代码
     * @param title 电站名称
     */
    @Query("match(f:Firm)-[:HAS_STATION]->(s:Station) where f.code={firmCode} and s.title={title} return s limit 1")
    Station findByFirmAndTitle(@Param("firmCode") Long firmCode, @Param("title") String title);

    @Query("match p=(role:Role)-[:HAS_STATION]->(stations)-[]-(t:StationType) where ID(role)={roleId} return p")
    Iterable<Station> findStationsByRoleId(@Param("roleId") Long roleId);

    @Query("match p=(role:Role)-[:HAS_OPTIONAL_STATION]->(stations)-[]-(t:StationType) where ID(role)={roleId} return p")
    Iterable<Station> findOptionalStationsByRoleId(@Param("roleId") Long roleId);

    Iterable<Station> findByTitleLike(String title);

    Iterable<Station> findByStorageCapacityLikeOrPhotovoltaicCapacityLikeOrWindCapacityLike(String stationScale1, String stationScale2, String stationScale3);

    Iterable<Station> findByStorageCapacityContainingOrPhotovoltaicCapacityContainingOrWindCapacityContaining(String stationScale1, String stationScale2, String stationScale3);

    Iterable<Station> findByStorageCapacityOrPhotovoltaicCapacityOrWindCapacity(Double capacity1, Double capacity2, Double capacity3);

    @Query("match(s:Station) where s.code in {codeList} return s")
    Iterable<Station> findStationByCodes(@Param("codeList") List<Long> codeList);

    Iterable<Station> findByTitleContaining(String title);

    @Query("match(s:Station)-[:STATIONTYPE_OF]->(t:StationType{code:{typeCode}}) return s")
    Iterable<Station> findStationsByTypeCode(@Param("typeCode") Long typeCode);

    /**
     * 根据单位查找绑定的电站
     * @param firmId 单位ID
     */
    @Query("match(f:Firm)-[:HAS_STATION]->(s:Station) where ID(f)={firmId} return s order by s.sn asc,s.createTime asc")
    Iterable<Station> findStationByFirmId(@Param("firmId") Long firmId);

    @Query("match(s:Station)-[:HAS_RESOURCE]->(res) where ID(res)={resId} return s limit 1")
    Station findByResourceId(@Param("resId") Long resId);

    /**
     * 电站绑定企业
     * @param id 电站ID
     * @param companyId 电站ID
     */
    @Query("start s=node({id}),c=node({companyId}) create (s)-[:HAS_RESOURCE{type:'Company'}]->(c)")
    void bindCompany(@Param("id") Long id, @Param("companyId") Long companyId);

    /**
     * 电站解绑企业
     * @param id 电站ID
     * @param companyId 电站ID
     */
    @Query("match(s:Station)-[r]->(c:Company) where ID(s)={id} and ID(c)={companyId} delete r")
    void unbindCompany(@Param("id") Long id, @Param("companyId") Long companyId);

    /**
     * 电站解绑所有企业
     * @param id 电站ID
     */
    @Query("match(s:Station)-[r]->(c:Company) where ID(s)={id} delete r")
    void unbindAllCompanys(@Param("id") Long id);

    /**
     * 查询电站的角色
     * @param roleIds
     * @return
     */
    @Query("match (s:Station)-[:HAS_ROLE]->(role:Role) where ID(role) IN {roleIds} return s")
    Iterable<Station> findStationsByRoleIds(@Param("roleIds") List<Long> roleIds);

    /**
     * 根据单位id和企业全称查询电站信息
     * @param firmId
     * @param enterpriseFullName
     * @return
     */
    @Query("match(f:Firm)-[:HAS_STATION]->(s:Station) where ID(f)={firmId} and s.enterpriseFullName={enterpriseFullName} return s limit 1")
    Station findByFirmAndEnterpriseFullName(@Param("firmId") Long firmId, @Param("enterpriseFullName") String enterpriseFullName);

    @Query("match (s:Station),(role:Role) where ID(s)={id} AND  role.name IN {names} create(s)-[:HAS_ROLE]->(role)")
    void bindRole(@Param("id") Long id,@Param("names") List<String> names);
    /**
     * 根据电站标题查找电站
     * @param title 电站标题
     * @return com.yunhe.authority.domain.authority.Station
     * @create 2021/2/25 10:20
     */
    @Query("match(s:Station) where s.title={title} return s limit 1")
    Station findByTitle(@Param("title") String title);


    @Query("match(s:Station)-[:HAS_RESOURCE]->(c:Company) where ID(c)={id} return s limit 1")
    Station findStationByBindCompanyId(@Param("id") Long id);

    Station findByEnterpriseFullName(String enterpriseFullName);

    /**
     * 根据真实园区id查询总园区
     * @param realStationId 真实园区ID
     */
    @Query("match(rs:RealStation)-[r:BELONG_TO_STATION]->(s:Station) where id(rs)={realStationId} return s")
    Station findStationByRealStationId(@Param("realStationId") Long realStationId);

    /**
     * 根据用户id查找绑定的电站
     * @param userId 用户ID
     */
    @Query("match(u:User)-[:HAS_STATION]->(s:Station) where ID(u)={userId} return s")
    Iterable<Station> findStationByUserId(@Param("userId") Long userId);
}
